/**
 * extjs log
 */
Ext.log = function(options , message) {

	var type = typeof(options);
	
	var level = "log";

	var msg = null;
	if (type == 'object') {
		msg = options.msg;
		if (!msg) {
			alert('Log Message[options.msg] is required! ');
		}
		level = options.level ? options.level : level;
	}
	else if (type != 'function') {
		msg = options;
	}
	// --- use firefox --
	if (Ext.firefoxVersion >0) {
		
	
		if (console) {
			var output = "";
			if (message) {
				output += message + " >> " + msg
			} else {
				output = msg;
			}

			if (level == "log") {
				console.debug(output);
			} else if (level == "info") {
				console.info(output);
			} else if ( level == "warn") {
				console.warn(output);
			} else if ( level == "error") {
				console.error(output);
			}
			
		}
		
	}
	
	if (Ext.isIE8 || Ext.isIE9 ) {
		if (console) {
			var output = "";
			if (message) {
				output += message + " >> " + msg
			} else {
				output = msg;
			}

			if (level == "log") {
				console.log(output);
			} else if (level == "info") {
				console.info(output);
			} else if ( level == "warn") {
				console.warn(output);
			} else if ( level == "error") {
				console.error(output);
			}
			
		}		
	}
	

}

/**
 * Contains a collection of all controllers that are created that have an id.
 */
Ext.define('Ext.app.ControllerManager',{
    extend: 'Ext.util.MixedCollection',
    singleton: true,
    
    /**
     * Registers one or more Controllers with the ControllerManager. You do not normally need to register controllers manually. Any
     * controller initialized with a {@link Ext.app.Controller#id} will be auto-registered.
     * @param {Ext.app.Controller...} controllers Any number of Controller instances
     */
    register : function() {
        for (var i = 0, s; (s = arguments[i]); i++) {
            this.add(s);
        }
    },
    
    /**
     * Unregisters one or more Controllers with the ControllerManager
     * @param {Ext.app.Controller...} controllers Any number of Controller instances
     */
    unregister : function() {
        for (var i = 0, s; (s = arguments[i]); i++) {
            this.remove(s);
        }
    }
});

Ext.define('Ext.app.Controller', {

    mixins: {
        observable: 'Ext.util.Observable'
    },

    
    onClassExtended: function(cls, data, hooks) {
        var className = Ext.getClassName(cls),
            match = className.match(/^(.*)\.controller\./);

        if (match !== null) {
            var namespace = Ext.Loader.getPrefix(className) || match[1],
                onBeforeClassCreated = hooks.onBeforeCreated,
                requires = [],
                modules = ['model', 'view', 'store'],
                prefix;

            hooks.onBeforeCreated = function(cls, data) {
                var i, ln, module,
                    items, j, subLn, item;

                for (i = 0,ln = modules.length; i < ln; i++) {
                    module = modules[i];

                    items = Ext.Array.from(data[module + 's']);

                    for (j = 0,subLn = items.length; j < subLn; j++) {
                        item = items[j];

                        prefix = Ext.Loader.getPrefix(item);

                        if (prefix === '' || prefix === item) {
                            requires.push(namespace + '.' + module + '.' + item);
                        }
                        else {
                            requires.push(item);
                        }
                    }
                }

                Ext.require(requires, Ext.Function.pass(onBeforeClassCreated, arguments, this));
            };
        }
    },

    
    constructor: function(config) {
        this.mixins.observable.constructor.call(this, config);

        Ext.apply(this, config || {});
        this.createGetters('model', this.models);
        this.createGetters('store', this.stores);
        this.createGetters('view', this.views);

        if (this.refs) {
            this.ref(this.refs);
        }

        var me = this;
        if (me.id){
            Ext.app.ControllerManager.register(me);
        }
    },
 
    
    destroy: function(){
        var me = this;
        
        if (me.id){
            Ext.app.ControllerManager.unregister(me);
        }
        
        delete me.application;
    },
	    
    init: function(application) {},

    
    onLaunch: function(application) {},
	
	openCoreWin : Ext.emptyFn,
	
	delayForOnLaunch: false,
	
	getDelayforOnLaunch:function() {
		return this.delayForOnLaunch;
	},
	
	// loadInitComp:null,

    createGetters: function(type, refs) {
        type = Ext.String.capitalize(type);

        var i      = 0,
            length = (refs) ? refs.length : 0,
            fn, ref, parts, x, numparts;

        for (; i < length; i++) {
            fn    = 'get';
            ref   = refs[i];
            parts = ref.split('.');
            numParts = parts.length;

            
            for (x = 0 ; x < numParts; x++) {
                fn += Ext.String.capitalize(parts[x]);
            }

            fn += type;

            if (!this[fn]) {
                this[fn] = Ext.Function.pass(this['get' + type], [ref], this);
            }
            
            this[fn](ref);
        }
    },

    ref: function(refs) {
        refs = Ext.Array.from(refs);
        
        var me = this,
            i = 0,
            length = refs.length,
            info, ref, fn;

        for (; i < length; i++) {
            info = refs[i];
            ref  = info.ref;
            fn   = 'get' + Ext.String.capitalize(ref);

            if (!me[fn]) {
                me[fn] = Ext.Function.pass(me.getRef, [ref, info], me);
            }
            me.references = me.references || [];
            me.references.push(ref.toLowerCase());
        }
    },

    addRef: function(ref) {
        return this.ref([ref]);
    },

    getRef: function(ref, info, config) {
        this.refCache = this.refCache || {};
        info = info || {};
        config = config || {};

        Ext.apply(info, config);

        if (info.forceCreate) {
            return Ext.ComponentManager.create(info, 'component');
        }

        var me = this,
            cached = me.refCache[ref];

        if (!cached) {
            me.refCache[ref] = cached = Ext.ComponentQuery.query(info.selector)[0];
            if (!cached && info.autoCreate) {
                me.refCache[ref] = cached = Ext.ComponentManager.create(info, 'component');
            }
            if (cached) {
                cached.on('beforedestroy', function() {
                    me.refCache[ref] = null;
                });
            }
        }

        return cached;
    },

    hasRef: function(ref) {
        return this.references && this.references.indexOf(ref.toLowerCase()) !== -1;
    },

    
    control: function(selectors, listeners) {
        this.application.control(selectors, listeners, this);
    },

    
    getController: function(name) {
        return this.application.getController(name);
    },

    
    getStore: function(name) {
        return this.application.getStore(name);
    },

    
    getModel: function(model) {
        return this.application.getModel(model);
    },

    
    getView: function(view) {
        return this.application.getView(view);
    }
});

/**
 * custom platform App object handle
 * @param {Object} config
 */
Ext.define('Ext.app.PlatformApp', {
    extend: 'Ext.app.Application',
    
    autoCreateViewport: false,

    
    constructor: function(config) {
        config = config || {};
        Ext.apply(this, config);

        this.callParent(arguments);

    },

	// --- record launch message ---
    onBeforeLaunch: function() {

        var me = this;

        if (me.enableQuickTips) {
            Ext.tip.QuickTipManager.init();
        }

        if (me.autoCreateViewport) {
            me.getView('Viewport').create();
        }

		me.launchControllers = {};
        me.launch.call(this.scope || this);
        me.launched = true;

        me.fireEvent('launch', this);
        var controllers = me.controllers.items,
            c,
            cLen        = controllers.length,
            controller;
			
        for (c = 0; c < cLen; c++) {
            controller = controllers[c];
            controller.onLaunch(this);
			me.launchControllers[controller.id] = 1;
        }
    },


	// --- extent mvc---
	addController : function(name) {
		var me = this;
		var controller = me.getController(name);

  		controller.init(me);
		if (me.launchControllers) {
			if (!me.launchControllers[controller.id]) {
				
				// --- add interceptor ---
				if (controller.loadInitComp) {
					controller.delayForOnLaunch = true;
				}

				if ( !controller.getDelayforOnLaunch() ) {
					controller.onLaunch(me);
					me.launchControllers[controller.id] = 1;
				}
			}
		}
		
	},
	
	/**
	 * get the lanch controller 
	 * @param {Object} name
	 */
	getLaunchController:function(name) {
		var me = this;
		if (me.launchControllers[name] ) {
			return  me.getController(name);
		} else {
			return null;
		}
		
	}
});

/**
 * rewirte application mapping 
 * @param {Object} config
 */
Ext.application = function(config) {
    Ext.require('Ext.app.PlatformApp');

    Ext.onReady(function() {
        new Ext.app.PlatformApp(config);
    });
};



